package com.sd365.permission.centre.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.sd365.common.core.annotation.mybatis.Pagination;
import com.sd365.common.core.annotation.stuffer.CommonFieldStuffer;
import com.sd365.common.core.annotation.stuffer.IdGenerator;
import com.sd365.common.core.annotation.stuffer.MethodTypeEnum;
import com.sd365.common.core.common.advice.MyPageInfo;
import com.sd365.common.core.common.exception.BusinessException;
import com.sd365.common.core.common.exception.code.BizErrorCode;
import com.sd365.common.core.common.exception.code.CommonErrorCode;
import com.sd365.common.core.common.service.AbstractBusinessService;
import com.sd365.common.core.context.BaseContextHolder;
import com.sd365.common.core.mq.ActionType;
import com.sd365.common.util.BeanException;
import com.sd365.common.util.BeanUtil;
import com.sd365.common.util.StringUtil;
import com.sd365.permission.centre.dao.mapper.TenantMapper;
import com.sd365.permission.centre.entity.Tenant;
import com.sd365.permission.centre.pojo.dto.DeleteTenantDTO;
import com.sd365.permission.centre.pojo.dto.TenantDTO;
import com.sd365.permission.centre.pojo.query.TenantQuery;
import com.sd365.permission.centre.service.TenantService;
import com.sd365.permission.centre.service.exception.UserCentreExceptionCode;
import com.sd365.permission.centre.service.util.SendMQMessageUtil;
import org.slf4j.Logger;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import tk.mybatis.mapper.entity.Example;

import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;

/**
 * @Class TenantServiceImpl
 * @Description 具体参考接口注释
 *  abel.zhan 2023/03/15 移除了数据同步的代码，不同库的同步采用 mysql数据库的本身的同步机制
 * @Author Administrator
 * @Date 2023-03-15  10:57
 * @version 1.0.0
 */
@Service
public class TenantServiceImpl extends AbstractBusinessService implements TenantService {
    /**
     * 操作租户dao
     */
    @Autowired
    TenantMapper tenantMapper;
    /**
     * id 生成器
     */
    @Autowired
    private IdGenerator idGenerator;

    @CommonFieldStuffer(methodType = MethodTypeEnum.ADD)
    @Override
    public Boolean add(@Valid TenantDTO tenantDTO) {
        Tenant tenant= BeanUtil.copy(tenantDTO, Tenant.class);
        if(!ObjectUtil.isNull(tenantMapper.queryByName(tenant.getName()))){
            throw new BusinessException(BizErrorCode.DATA_SEARCH_FOUND_MANNY,new Exception("记录已经存在不可重复"));
        }
        return tenantMapper.insert(tenant) > 0;
    }

    @Pagination
    @CommonFieldStuffer(methodType = MethodTypeEnum.QUERY)
    @Override
    public List<TenantDTO> commonQuery(TenantQuery tenantQuery) {
            Tenant tenant = new Tenant();
            tenant.setName(tenantQuery.getName());
            tenant.setAccount(tenantQuery.getAccount());
            List<Tenant> tenants= tenantMapper.commonQuery(tenant);
            setPageInfo2BaseContextHolder((Page)tenants);
            //对象转化 po list to dto list
            return BeanUtil.copyList(tenants,TenantDTO.class);
    }

    @CommonFieldStuffer(methodType = MethodTypeEnum.DELETE)
    @Override
    public Boolean remove(Long id, Long version) {
            Example example=new Example(Tenant.class);
            example.createCriteria().andEqualTo("id",id).andEqualTo("version",version);
            return  tenantMapper.deleteByExample(example)>0;
    }

    @CommonFieldStuffer(methodType = MethodTypeEnum.UPDATE)
    @Override
    public Boolean modify(@NotNull @Valid TenantDTO tenantDTO) {
            if(checkTheSameCodeTenant(tenantDTO.getId(),tenantDTO.getAccount())){
                throw new BusinessException(BizErrorCode.DATA_SEARCH_FOUND_MANNY,new Exception("企业代号不可以重复"));
            }
            Tenant tenant= BeanUtil.copy(tenantDTO, Tenant.class);
            Example example=new Example(Tenant.class);
            example.createCriteria().andEqualTo("id",tenantDTO.getId()).andEqualTo("version",tenantDTO.getVersion());
            return  tenantMapper.updateByExample(tenant,example)>0;
    }

    /**
     *  判断是否存在同code的租户
     * @param id  当前修改的记录id
     * @param code  当前修改的记录的 code
     * @return true代表不存在 false存在
     */
    private boolean checkTheSameCodeTenant(Long id,String code){
        Example example=new Example(Tenant.class);
        example.createCriteria().andNotEqualTo("id",id).andEqualTo("code",code);
        return tenantMapper.selectByExample(example).isEmpty();
    }


    @CommonFieldStuffer(methodType = MethodTypeEnum.DELETE)
    @Override
    public Boolean batchDelete(@NotEmpty DeleteTenantDTO[] deleteTenantDTOS) {
        Assert.notEmpty(deleteTenantDTOS,"批量删除参数不可以为空");
        List<Object> currentTenant = new ArrayList<>();
        for(DeleteTenantDTO deleteTenantDTO : deleteTenantDTOS){
            Example example=new Example(Tenant.class);
            example.createCriteria().andEqualTo("id",deleteTenantDTO.getId()).andEqualTo("version",deleteTenantDTO.getVersion()) ;
            // 如果异常则整个事务回滚
            if(tenantMapper.deleteByExample(example)<=0){
                throw new BusinessException(BizErrorCode.DATA_DELETE_NOT_FOUND,
                        new Exception(String.format("删除的记录id %d 没有匹配到版本",deleteTenantDTO.getId())));
            }
        }
        return Boolean.TRUE;
    }

    @Override
    public TenantDTO queryById(Long id) {
            Tenant tenant= tenantMapper.selectById(id);
            return tenant!=null ? BeanUtil.copy(tenant, TenantDTO.class) : new TenantDTO();
    }

    @CommonFieldStuffer(methodType = MethodTypeEnum.QUERY)
    @Override
    public TenantDTO queryByName(String name){
            Tenant tenant= tenantMapper.queryByName(name);
            return tenant!=null ? BeanUtil.copy(tenant, TenantDTO.class) : new TenantDTO();
    }
}
